const express = require("express");
const compression = require("compression");
const path = require("path");
const fs = require("fs");

const app = express();

// 配置 gzip 压缩
app.use(
    compression({
        level: 9, // 最高压缩级别
        threshold: 0, // 所有响应都压缩
        filter: (req, res) => {
            // 只允许gzip压缩
            if (req.headers["accept-encoding"]?.includes("gzip")) {
                return true;
            }
            return false;
        },
        // 只启用 gzip 压缩
        strategy: compression.GZIP,
    })
);

// 设置静态文件目录
const distPath = path.join(process.cwd(), "src", "public", "dist", "webpack-react-start-gzip");
console.log("静态文件目录:", distPath);

// 提供静态文件
// MIME类型映射
const mimeTypes = {
    ".js": "application/javascript",
    ".mjs": "application/javascript",
    ".css": "text/css",
    ".html": "text/html",
    ".json": "application/json",
    ".png": "image/png",
    ".jpg": "image/jpeg",
    ".gif": "image/gif",
    ".svg": "image/svg+xml",
    ".ico": "image/x-icon",
};

// Gzip处理中间件
const handleGzip = (req, res, next) => {
    const originalSetHeader = res.setHeader;
    res.setHeader = function (name, value) {
        if (name === "Content-Type" && req.url.endsWith(".gz")) {
            const acceptEncoding = req.headers["accept-encoding"] || "";
            if (acceptEncoding.includes("gzip")) {
                const actualPath = req.url.slice(0, -3);
                const ext = path.extname(actualPath);
                arguments[1] = mimeTypes[ext] || "application/octet-stream";
                res.setHeader("Content-Encoding", "gzip");
                res.setHeader("Vary", "Accept-Encoding");
            }
        }
        return originalSetHeader.apply(this, arguments);
    };
    next();
};

// 自定义静态文件中间件，优先使用 .gz 文件
app.get("*.js", function (req, res, next) {
    const position = path.join(process.cwd(), "src", "public", "dist");
    // 替换路径前缀
    const modifiedUrl = req.url.replace("/webpack-react-start/", "/webpack-react-start-gzip/");
    const gzipPath = path.join(position, modifiedUrl + ".gz");
    if (fs.existsSync(gzipPath)) {
        req.url = modifiedUrl + ".gz";
        res.set("Content-Encoding", "gzip");
    } else {
        req.url = modifiedUrl;
    }
    res.set("Content-Type", "text/javascript");
    next();
});

app.get("*.css", function (req, res, next) {
    const position = path.join(process.cwd(), "src", "public", "dist");
    // 替换路径前缀
    const modifiedUrl = req.url.replace("/webpack-react-start/", "/webpack-react-start-gzip/");
    const gzipPath = path.join(position, modifiedUrl + ".gz");
    if (fs.existsSync(gzipPath)) {
        req.url = modifiedUrl + ".gz";
        res.set("Content-Encoding", "gzip");
    } else {
        req.url = modifiedUrl;
    }
    res.set("Content-Type", "text/css");
    next();
});

// 静态文件服务配置
app.use(
    "/webpack-react-start-gzip",
    handleGzip,
    express.static(distPath, {
        setHeaders: (res, filePath) => {
            // 设置缓存控制
            res.setHeader("Cache-Control", "public, max-age=31536000"); // 1年缓存

            // 设置Content-Type
            const ext = path.extname(filePath);
            if (!filePath.endsWith(".gz")) {
                res.setHeader("Content-Type", mimeTypes[ext] || "application/octet-stream");
            }
        },
        // index: false // 禁用目录索引
    })
);

// 处理所有路由请求，返回 index.html
app.get("/webpack-react-start/*", (req, res) => {
    // res.sendFile(path.join(distPath, "static", "index.html"));
    res.sendFile(path.join(distPath, "index.html"));
});

// 根路径重定向到应用
app.get("/", (req, res) => {
    res.redirect("/webpack-react-start/");
});

const PORT = process.env.PORT || 3002;
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}/webpack-react-start/`);
});
